﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NexTrackDesktop.Media;
using System.Diagnostics;

namespace NexTrackDesktop.NexTrack
{
    class NexTrackServiceAdapter : MainServiceAdapter
    {
        private MainService.Service mainservice;
        private string PartyID;

        public NexTrackServiceAdapter()
        {
            mainservice = new MainService.Service();
        }

        public override string CreateParty(string description, string access_code, int voteLimit, int voteReplen)
        {
            var createinfo = mainservice.CreateParty(description, access_code, 0, voteLimit, voteReplen, false);
            PartyID = createinfo.PartyID;
            return PartyID;
        }

        public override void AddSong(Media.Song song)
        {
            RequireParty();

            if (song.Artist.Length > 50)
                song.Artist = song.Artist.Substring(0, 47) + "...";

            if (song.Album.Length > 50)
                song.Album = song.Album.Substring(0, 47) + "...";

            if (song.Title.Length > 50)
                song.Title = song.Title.Substring(0, 47) + "...";

            var response = mainservice.AddSong(PartyID, song.Artist, song.Album, song.Title);

            if (string.IsNullOrEmpty(response))
                return;
            else
            {
                song.SongID = response;
                songs.Add(song);
            }
        }

        public override Media.Song GetNowPlaying()
        {
            RequireParty();

            var nowPlayingInfo = mainservice.GetNowPlaying(PartyID);

            Song result = songs.First(s => s.SongID == nowPlayingInfo.SongID);

            return result;
        }

        public override List<Media.QueueItem> GetQueue()
        {
            RequireParty();

            try
            {
                var queueInfo = mainservice.GetQueue(PartyID);

                queue.Clear();

                foreach (var item in queueInfo)
                {
                    Song song = songs.FirstOrDefault(s => s.SongID.ToUpper() == item.Song.SongID.ToUpper());

                    if (song == null)
                        throw new InvalidOperationException("Error synchronizing with NexTrack server");

                    QueueItem qi = new QueueItem(song)
                    {
                        UpVotes = item.UpVotes,
                        DownVotes = item.DownVotes
                    };

                    queue.Add(qi);
                }
            }
            catch (System.Net.WebException we)
            {
                Debug.Print("There was an error communicating with the web service.");
                Debug.Print(we.ToString());
            }

            return queue.ToList();
        }
        


        public override void RemoveSong(Media.Song song)
        {
            RequireParty();

            throw new NotImplementedException();
        }

        public override void UpdateNowPlaying(Media.Song song)
        {
            RequireParty();

            if (song.SongID == null)
                throw new InvalidOperationException("Can only update with a song that has been added to the server!");

            int retries = 0;

            while (retries++ < 10)
            {
                try
                {
                    mainservice.UpdateNowPlaying(PartyID, song.SongID);
                    return;
                }
                catch (System.Net.WebException we)
                {
                    Debug.Print("There was an error communicating with the web service.");
                    Debug.Print(we.ToString());
                }
            }

            throw new Exception("Error synchronizing with NexTrack server while updating the now playing song.");
        }

        private void RequireParty()
        {
            if (PartyID == null)
                throw new InvalidOperationException("Party not created. Call createparty first.");
        }
    }
}
